/* * License (BSD Style License): * Copyright (c) 2011 * Software Engineering * Department of Computer Science * Technische Universität Darmstadt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Software Engineering Group or Technische * Universität Darmstadt nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package de.tud.cs.st.vespucci.vespucci_model.diagram.edit.parts; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.PolygonDecoration; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Transform; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; /** * Decoration which paints an arrow pointing outwards and a question * mark which was originally meant to be painted into a triangle having been * manually constructed using the setTemplate method as in * {@link de.tud.cs.st.vespucci.vespucci_model.diagram.edit.parts.WarningEditPart#createTargetDecoration()} * * @author Dominic Scheurer */ public class WarningDecoration extends PolygonDecoration { private static final int LINE_XPOS = 5; private static final int LINE_Y1 = -5; private static final int LINE_Y2 = 2; private static final int DOT_POS_X = 5; private static final int DOT_POS_Y = 4; private static final Point TRIANGLE_P1 = new Point(15, 8); private static final Point TRIANGLE_P2 = new Point(5, -9); private static final Point TRIANGLE_P3 = new Point(-5, 8); private Transform transform = new Transform(); private Point location = new Point(); public WarningDecoration() { transform.setScale(1.0); } @Override public void paint(Graphics graphics) { graphics.setLineWidth(1); graphics.setBackgroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); paintTriangle(graphics); paintExclamationMark(graphics); } @Override public boolean isOpaque() { return true; } @Override protected boolean shapeContainsPoint(int x, int y) { return getBounds().contains(x, y); } @Override public Rectangle getBounds() { int xLeft = Integer.MAX_VALUE, xRight = 0, yTop = Integer.MAX_VALUE, yBottom = 0; PointList trianglePoints = createTrianglePoints(); if (trianglePoints.size() < 3) { return super.getBounds(); // May happen at diagram startup } for (int i = 0; i < trianglePoints.size(); i++) { Point trianglePoint = trianglePoints.getPoint(i); int x = trianglePoint.x; int y = trianglePoint.y; if (x < xLeft) { xLeft = x; } if (x > xRight) { xRight = x; } if (y < yTop) { yTop = y; } if (y > yBottom) { yBottom = y; } } return new Rectangle(xLeft - 1, yTop - 1, xRight - xLeft + 2, yBottom - yTop + 2); } @Override public void setReferencePoint(Point ref) { super.setReferencePoint(ref); Point pt = Point.SINGLETON; pt.setLocation(ref); pt.negate().translate(location); setRotation(Math.atan2(pt.y, pt.x)); } @Override public void setLocation(Point p) { super.setLocation(p); location.setLocation(p); transform.setTranslation(p.x, p.y); } @Override public void setRotation(double angle) { super.setRotation(angle); // Triangle shall not be turned upside down if (Math.abs(angle) >= Math.PI / 2) { if (angle > 0) { angle -= Math.PI; } else { angle += Math.PI; } } transform.setRotation(angle); } private PointList createTrianglePoints() { PointList trianglePoints = new PointList(); if (transform == null) { // Transform object may be null at application startup... return trianglePoints; } trianglePoints.addPoint(transform.getTransformed(TRIANGLE_P1)); trianglePoints.addPoint(transform.getTransformed(TRIANGLE_P2)); trianglePoints.addPoint(transform.getTransformed(TRIANGLE_P3)); trianglePoints.addPoint(transform.getTransformed(TRIANGLE_P1)); return trianglePoints; } private void paintTriangle(Graphics graphics) { graphics.setBackgroundColor(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); graphics.fillPolygon(createTrianglePoints()); graphics.drawPolygon(createTrianglePoints()); } private void paintExclamationMark(Graphics graphics) { Point lineStartPoint = new Point(LINE_XPOS, LINE_Y1); Point lineEndPoint = new Point(LINE_XPOS, DOT_POS_Y + 2); graphics.drawLine(transform.getTransformed(lineStartPoint), transform.getTransformed(lineEndPoint)); graphics.setBackgroundColor(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); Point separatorTopLeftPoint = new Point(LINE_XPOS - 2, LINE_Y2); Point separatorBottomRightPoint = new Point(LINE_XPOS + 2, DOT_POS_Y); PointList separatorPoints = new PointList(5); separatorPoints.addPoint(transform.getTransformed(separatorTopLeftPoint)); separatorPoints.addPoint(transform.getTransformed(new Point(separatorBottomRightPoint.x, separatorTopLeftPoint.y))); separatorPoints.addPoint(transform.getTransformed(separatorBottomRightPoint)); separatorPoints.addPoint(transform.getTransformed(new Point(separatorTopLeftPoint.x, separatorBottomRightPoint.y))); separatorPoints.addPoint(transform.getTransformed(separatorTopLeftPoint)); graphics.fillPolygon(separatorPoints); } }